package com.game.utils;


//import com.csvreader.CsvReader;
//import info.monitorenter.cpdetector.CharsetPrinter;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class FileHelper {
    public static String readFile(String fileName) {
        return readFile(fileName, (String)null);
    }

    public static String readFile(String fileName, String charsetName) {
        File file = new File(fileName);
        if (!file.exists())
            return null;
        if (charsetName == null)
            return readFile(file, "UTF-8");
        return readFile(file, charsetName);
    }

    public static byte[] read(String filename) {
        FileChannel fc = null;
        try {
            fc = (new RandomAccessFile(filename, "r")).getChannel();
            MappedByteBuffer byteBuffer = fc.map(FileChannel.MapMode.READ_ONLY, 0L, fc.size()).load();
            System.out.println(byteBuffer.isLoaded());
            byte[] result = new byte[(int)fc.size()];
            if (byteBuffer.remaining() > 0)
                byteBuffer.get(result, 0, byteBuffer.remaining());
            return result;
        } catch (IOException e) {
            e.printStackTrace();
            return new byte[0];
        } finally {
            try {
                fc.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static String readFile(File file, String charsetName) {
        FileInputStream fin = null;
        InputStreamReader inReader = null;
        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();
        try {
            fin = new FileInputStream(file);
            inReader = new InputStreamReader(fin, charsetName);
            br = new BufferedReader(inReader);
            char[] charBuffer = new char[1024];
            int n = 0;
            while ((n = br.read(charBuffer)) != -1)
                sb.append(charBuffer, 0, n);
            return sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fin != null)
                try {
                    fin.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            if (inReader != null)
                try {
                    inReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
        return null;
    }

//    public static List<String[]> readCsvFile(File file) {
//        return readFileByDelimiter(file, ',');
//    }
//
//    public static List<String[]> readFileByDelimiter(File file, char delimiter) {
//        List<String[]> values = (List)new ArrayList<>();
//        CsvReader reader = null;
//        try {
//            CharsetPrinter charsetPrinter = new CharsetPrinter();
//            String charset = charsetPrinter.guessEncoding(file);
//            reader = new CsvReader(file.getPath(), delimiter, Charset.forName(charset));
//            while (reader.readRecord())
//                values.add(reader.getValues());
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            reader.close();
//        }
//        return values;
//    }

    public static String[] resolveFileContent(String fileContent, List<String[]> allValues) {
        String[] lineContent = fileContent.split("\r\n");
        if (lineContent == null || lineContent.length <= 1)
            return null;
        String[] attributeNames = lineContent[1].split("\t", -1);
        if (attributeNames == null || attributeNames.length == 0)
            return null;
        for (int i = 2; i < lineContent.length; i++) {
            String[] attributeValues = lineContent[i].split("\t", -1);
            allValues.add(attributeValues);
        }
        return attributeNames;
    }

    public static void fileBytesWrite(String fileName, byte[] bytes, boolean append) throws Exception {
        File file = new File(fileName);
        if (!file.exists()) {
            if (file.getParentFile() != null)
                file.getParentFile().mkdir();
            file.createNewFile();
        }
        fileBytesWrite(file, bytes, append);
    }

    public static void fileBytesWrite(File file, byte[] bytes, boolean append) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file, append);
            fos.write(bytes);
            fos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fos != null)
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }

    public static void saveFile(File file, String content, boolean append) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file, append);
            fos.write(content.getBytes("UTF-8"));
            fos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fos != null)
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }

    public static void saveFile(String fileName, String content, boolean append) {
        File file = new File(fileName);
        if (!file.exists())
            try {
                if (file.getParentFile() != null)
                    file.getParentFile().mkdirs();
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        saveFile(file, content, append);
    }

    public static void saveObjectToXml(Object obj, String fileName, boolean isAppend) {
        File fo = new File(fileName);
        if (!fo.exists()) {
            fo.getParentFile().mkdirs();
            try {
                fo.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            FileOutputStream fos = new FileOutputStream(fo, isAppend);
            XMLEncoder encoder = new XMLEncoder(fos);
            encoder.writeObject(obj);
            encoder.flush();
            encoder.close();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void unZipFiles(String zipPath, String descDir) throws IOException {
        unZipFiles(new File(zipPath), descDir);
    }

    public static boolean unZipFiles(File zipFile, String descDir) throws IOException {
        File pathFile = new File(descDir);
        if (!pathFile.exists())
            pathFile.mkdirs();
        ZipFile zip = new ZipFile(zipFile);
        for (Enumeration<? extends ZipEntry> entries = zip.entries(); entries.hasMoreElements(); ) {
            ZipEntry entry = entries.nextElement();
            String zipEntryName = entry.getName();
            InputStream in = zip.getInputStream(entry);
            String outPath = (descDir + zipEntryName).replaceAll("\\*", "/");
            File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
            if (!file.exists())
                file.mkdirs();
            if ((new File(outPath)).isDirectory())
                continue;
            System.out.println(outPath);
            OutputStream out = new FileOutputStream(outPath);
            byte[] buf1 = new byte[1024];
            int len;
            while ((len = in.read(buf1)) > 0)
                out.write(buf1, 0, len);
            in.close();
            out.close();
        }
        System.out.println("******************解压完毕*************");
        return true;
    }

    public static void copy(String path, String copyPath) throws IOException {
        File filePath = new File(path);
        if (filePath.isDirectory()) {
            File[] list = filePath.listFiles();
            for (int i = 0; i < list.length; i++) {
                String newPath = path + File.separator + list[i].getName();
                String newCopyPath = copyPath + File.separator + list[i].getName();
                File file = new File(copyPath);
                file.mkdirs();
                copy(newPath, newCopyPath);
            }
        } else if (filePath.isFile()) {
            DataInputStream read = new DataInputStream(new BufferedInputStream(new FileInputStream(path)));
            DataOutputStream write = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(copyPath)));
            byte[] buf = new byte[524288];
            int len;
            while ((len = read.read(buf)) > 0)
                write.write(buf, 0, len);
            read.close();
            write.close();
        } else {
            System.err.println("请正确输入路径或文件名");
        }
    }

    public static Properties loadProperties(String fileName, String charset) {
        FileInputStream fin = null;
        InputStreamReader inReader = null;
        Properties properties = new Properties();
        try {
            fin = new FileInputStream(fileName);
            properties.load(fin);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fin != null)
                try {
                    fin.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            if (inReader != null)
                try {
                    inReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
        return properties;
    }

    public static void main(String[] args) throws IOException {
        copy("src", "src1");
    }
}
